/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package modelo;

import modelo.tipos.TipoErroSintatico;
import modelo.tipos.TipoToken;
import static modelo.tipos.TipoToken.ATRIBUICAO;
import static modelo.tipos.TipoToken.COLCHETES_ABRE;
import static modelo.tipos.TipoToken.COLCHETES_FECHA;
import static modelo.tipos.TipoToken.COMPARADOR;
import static modelo.tipos.TipoToken.DOIS_PONTOS;
import static modelo.tipos.TipoToken.OPERADOR;
import static modelo.tipos.TipoToken.PARENTESES_ABRE;
import static modelo.tipos.TipoToken.PARENTESES_FECHA;
import static modelo.tipos.TipoToken.PONTO;
import static modelo.tipos.TipoToken.PONTOEV;
import static modelo.tipos.TipoToken.SEPARADOR;

/**
 *
 * @author clodbrasilino
 */
public class ErroSintatico extends Exception implements IErro {

    private Token token;
    private Token tokenEsperado = null;
    private TipoErroSintatico tipoErro;

    public ErroSintatico() {
        super();
    }

    public ErroSintatico(Token token, TipoErroSintatico tipoErro) {
        super();
        this.token = token;
        this.tipoErro = tipoErro;
    }

    public ErroSintatico(Token token, Token tokenEsperado, TipoErroSintatico tipoErro) {
        super();
        this.token = token;
        this.tipoErro = tipoErro;
        this.tokenEsperado = tokenEsperado;
        this.tokenEsperado.setToken(nomeToken(this.tokenEsperado.getToken(), tokenEsperado.getTipo()));
    }

    private String nomeToken(String nome, TipoToken tipo) {
        if (nome == null) {
            switch (tipo) {
                case ATRIBUICAO:
                    return ":=";
                case COLCHETES_ABRE:
                    return "[";
                case COLCHETES_FECHA:
                    return "]";
                case COMPARADOR:
                    return "= ou < ou > ou <> ou <= ou >=";
                case DOIS_PONTOS:
                    return ":";
                case OPERADOR:
                    return "+ ou - ou * ou /";
                case PARENTESES_ABRE:
                    return "(";
                case PARENTESES_FECHA:
                    return ")";
                case PONTO:
                    return ".";
                case PONTOEV:
                    return ";";
                case SEPARADOR:
                    return ",";
            }
        }
        return nome;
    }

    public TipoErroSintatico getTipoErro() {
        return tipoErro;
    }

    public void setTipoErro(TipoErroSintatico tipoErro) {
        this.tipoErro = tipoErro;
    }

    public Token getToken() {
        return token;
    }

    public void setToken(Token token) {
        this.token = token;
    }

    @Override
    public String errosToString() {
        switch (this.getTipoErro()) {
            case TOKEN_ESPERADO:
                if (this.tokenEsperado != null && this.tokenEsperado.getToken() == null) {
                    return "Token INESPERADO: \"" + this.getToken().getToken() + "\" na linha " + this.getToken().getLinha() + ". "
                            + "Tipo ESPERADO: \"" + this.tokenEsperado.getTipo() + "\".\n";
                }
                if (this.tokenEsperado != null) {
                    return "Token INESPERADO: \"" + this.getToken().getToken() + "\" na linha " + this.getToken().getLinha() + ". "
                            + "ESPERADO: \"" + this.tokenEsperado.getToken() + "\".\n";
                } else {
                    return "Token INESPERADO: \"" + this.getToken().getToken() + "\" na linha " + this.getToken().getLinha() + ".\n";
                }
            case FIM_INESPERADO:
                return "Fim inesperado do programa. \n";
                 
        }
        return "";
    }
}
